#include <iostream>
#include <memory>

/* 简单工厂模式 */
class Fruit{
public:
    virtual void name() = 0;
private:   
};

class Apple : public Fruit{
public:
    void name() override{
        std::cout << "I'm a apple" << std::endl;
    }
};

class Banana : public Fruit{
public:
    void name() override {
        std::cout << "I'm a banana" << std::endl;
    }
};

// class FruitFactory {
// public:
//     static std::shared_ptr<Fruit> create(const std::string &name) {
//         if (name == "苹果") {
//             return std::make_shared<Apple>();
//         } else {
//             return std::make_shared<Banana>();
//         }
//     }
// };

/* 工厂方法模式 */
// class FruitFactory {
// public:
//     virtual std::shared_ptr<Fruit> createFruit() = 0;
// };

// class AppleFactory : public FruitFactory {
// public:
//     virtual std::shared_ptr<Fruit> createFruit() override {
//         return std::make_shared<Apple>();
//     }
// };

// class BananaFactory : public FruitFactory {
// public:
//     virtual std::shared_ptr<Fruit> createFruit() override {
//         return std::make_shared<Banana>();
//     }
// };


class Animal {
    public:
        virtual void name() = 0;
};

class Lamp : public Animal {
    public:
        virtual void name() override { 
            std::cout << "I'm a Lamp" << std::endl;
        }
};

class Dog : public Animal {
    public:
        virtual void name() override {
            std::cout << "I'm  a dog" << std::endl;
        }
};

class Factory {
    public: 
        virtual std::shared_ptr<Fruit> getFruit(const std::string& name) = 0;
        virtual std::shared_ptr<Animal> getAnimal(const std::string& name) = 0;
};

class FruitFactory : public Factory {
    public:
    virtual std::shared_ptr<Fruit> getFruit(const std::string& name) override{
        if (name == "苹果") {
            return std::make_shared<Apple>();
        } else {
            return std::make_shared<Banana>();
        }
    }
    virtual std::shared_ptr<Animal> getAnimal(const std::string& name) override{
        return std::shared_ptr<Animal>();
    }
};

class AnimalFactory : public Factory {
    public:
    virtual std::shared_ptr<Fruit> getFruit(const std::string& name) override {
        return std::shared_ptr<Fruit>();
    }
    virtual std::shared_ptr<Animal> getAnimal(const std::string& name) override {
        if (name == "山羊") {
            return std::make_shared<Lamp>();
        } else {
            return std::make_shared<Dog>();
        }
    }
};

class FactoryProducer {
    public: 
        static std::shared_ptr<Factory> create(const std::string &name) {
            if (name == "水果") {
                return std::make_shared<FruitFactory>();
            } else {
                return std::make_shared<AnimalFactory>();
            }
        }
};

int main() {
    std::shared_ptr<Factory> ff = FactoryProducer::create("水果");
    std::shared_ptr<Fruit> fruit = ff->getFruit("苹果");
    fruit->name();
    fruit = ff->getFruit("香蕉");
    fruit->name();
    ff = FactoryProducer::create("动物");
    std::shared_ptr<Animal> animal = ff->getAnimal("山羊");
    animal->name();
    animal = ff->getAnimal("小狗");
    animal->name();
    return 0;
}






// int main() {
//     std::shared_ptr<FruitFactory> ff(new AppleFactory());
//     std::shared_ptr<Fruit> fruit1 = ff->createFruit();
//     fruit1->name();
//     ff.reset(new BananaFactory());
//     std::shared_ptr<Fruit> fruit2 = ff->createFruit();
//     fruit2->name();
//     return 0;
// }